; M0DGQ ; ATU TX ; TEST TWO INDEPENDENT VARIBLES ARE TRANSFERED TO RX ; ROTARY ENCODER TO INC/DEC VAR_2 ; NOW ENCODER ALSO INC/DEC VAR_1 ; ENDSTOPS ADDED TO VAR_C AND VAR_L ; LCD INDICATION OF L AND C VARIABLES ; CLEAN UP CODE AND COMMENTS ; CHANGED C MIN END STOP TO ZERO ; TMR0 INTERUPT ROUTINE ADDED FOR LINK TEST ; LCD COMMANDS NOW TEST BUSY FLAG INSTEAD OF USING FIXED DELAYS ; ISR FOR LINK TEST ADDED ; LCD INDUCTOR/CAPACITOR DISPLAY TOGGLE ;******************************************************************************************************************** LIST p=16F628A ;tell assembler what chip we are using INCLUDE "P16F628A.inc" ;include the defaults for the chip __CONFIG 0x3F18 ;sets the configuration settings ;INT 4mhZ OSC ;************************************************************************************************************** CBLOCK 0x020 COUNT_0 ; TEMP_0 ;TEMP VARIABLE USED FOR COMPARISONS OF OLD AND NEW ENCODER READINGS (XOR). OLD ;OLD (PREVIOUS) ENCODER VALUE NEW ;NEW (LATEST) ENCODER VALUE. DIV_COUNT_DOWN ;4 TRANSISTION DOWN REG * SOME ENCODERS PRODUCE FOUR TRANSITIONS PER INDENT DIV_COUNT_UP ;4 TRANSITION UP REG * DLY_COUNT1 ;SWITCH BOUNCE COUNTER DELAY REG DLY_COUNT2 ; " " " " " DLY_COUNT3 DLY_COUNT4 VAR_L VAR_C LC_VAR dly_count3 ;used in delay routine tmp1 ;temporary storage tmp2 templcd ;TEMP STORE FOR 4 BIT MODE templcd2 BCD_L BCD_H BIN BIN_COUNT BIN_TEMP CONVERT_BYTE_LO ;Binary inputs for decimal convert routine CONVERT_BYTE_HI HUND_C TENS_C ONES_C HUND_L TENS_L ONES_L WREG_TEMP STATUS_TEMP COMPARE COUNT_ISR ENDC ;END OF DATA MEMORY ;*************************************************************************** #DEFINE LC_BUTT PORTB,0 ;MAKE INPUT FOR LC BUTTON TOGGLE #DEFINE ENCODER PORTB ;ENCODER INPUTS BIT 3 AND 4 #DEFINE LINK_OK PORTB,6 ;LINK OK LED #DEFINE C_LED PORTB,7 ;TOGGLES LED WHEN L/C BUTTON PRESSED #DEFINE LCD_PORT PORTA #DEFINE LCD_RS PORTA,4 #DEFINE LCD_RW PORTA,6 #DEFINE LCD_E PORTA,7 ;*************************************************************************** errorlevel -302, -305 ;GET RID OF ANOYING COMPILER ERROR MESSAGE ORG 0x0000 ;org sets the origin, 0x0000 for the 16F628, GOTO START ;this is where the program starts running ;********************************************************************************** ORG 0x0004 ;INTERUPT RESET VECTOR ISR ;THE FOLLOWING ROUTINE CHECKS LINK INTEGRETY USING TMR0 AND 8 BIT COUNTER TO GENERATE A LINK CHECK EVERY 3 SECONDS BCF INTCON,GIE ;NO MORE INTERUPTS WHILE ISR EXECUTED BCF INTCON,T0IE ;DISABLE TIMER 0 INTERUPT ;CONTEXT SAVING MOVWF WREG_TEMP ;SAVE W IN WREG_TEMP MOVF STATUS,W ;SAVE STATUS IN STATUS_TEMP BANKSEL STATUS_TEMP ;SELECT CORRECT BANK FOR STATUS REG IN ISR !!! if you do not do this status reg may not have original value restored!********* MOVWF STATUS_TEMP ;SAVE STATUS INCF COUNT_ISR BTFSS STATUS,Z ;IF COUNTER HAS ROLLED OVER TO ZERO THEN DO LINK CHECK, IF NOT THEN CONTEXT RESTORE AND BACK TO MAIN PROGRAM GOTO BRANCH_1 CALL SEND_RS232 ;RESTORE PREVIOUS VAR L AND C VALUES IN RX IN CASE LINK OR POWER FAILURE IN RX ;FLUSH RECEIVE BUFFER MOVF RCREG,W MOVF RCREG,W MOVF RCREG,W ;SEND COMPARISON BYTE TO RX MOVLW b'11111111' ;LOAD COMPARISON RS232 BYTE MOVWF TXREG ;SEND L DATA IN W BANKSEL TRISA ;RAM PAGE 1 BTFSS TXSTA,TRMT ;HAS TX FINISHED? GOTO $-1 ;NO, GO BACK AND WAIT FOR TXSTA,TRMT BIT TO SET HIGH BANKSEL PORTA ;TX FINISHED SO BACK TO RAM PAGE 0 CALL DELAY_2 ;WAIT 5mS FOR RS232 TO CIRCULATE ROUND LOOP BCF LINK_OK ;TURN OFF LINK OK LED, IF LINK OK THEN LED WILL BE SWITCHED ON AGAIN IN APPROX 12uS, HUMAN EYE WILL NOT SEE LED OFF. BTFSS PIR1,RCIF ;CHECK FOR RECEIVED DATA GOTO BRANCH_1 ;LINK BAD SO SKIP MOVFW RCREG ;MOVE USART RCREG INTO COMPARE REG ( THIS SHOULD BE 11111111 IF LINK GOOD ) MOVWF COMPARE ; MOVLW b'11111111' ;LOAD COMPARISON RS232 BYTE XORWF COMPARE,W BCF LINK_OK ; BTFSS STATUS,Z ;ARE THEY THE SAME? THIS WILL LOOP CONTINUOSLY UNTIL COMPARISON IS THE SAME GOTO BRANCH_1 ;NO, LINK BAD SO GO BACK TO BEGINING OF LOOP UNTIL COMPARISON BYTE RECEIVED, WILL LOOP CONTINOUSLY UNTIL BYTE RECEIVED BSF LINK_OK ;YES, LINK GOOD SO SET LINK_OK LED BRANCH_1 ;CONTEXT RESTORE MOVF STATUS_TEMP,W ;RESTORE STATUS REGISTER TO PREVIOUS VALUE - THIS DOES NOT AFFECT ANY STATUS BITS MOVWF STATUS ;PUT INTO STATUS REGISTER SWAPF WREG_TEMP,F ;SWAP W REG NIBBLES SWAPF WREG_TEMP,W ;SWAP NIBBLES AGAIN AND PUT INTO W REGISTER - THIS RESTORES W REGISTER TO PREVIOUS VALUE WITHOUT AFFECTING STATUS BITS BCF INTCON,T0IF ;CLEAR TMR0 INTERUPT OVERFLOW FLAG BSF INTCON,T0IE ;ENABLE TMR0 INTERUPT BSF INTCON,GIE ;ENABLE GIE RETURN ;*************************************************************************** START MOVLW 0x07 ;LOAD 0x07 INTO W MOVWF CMCON ;TURN COMPARATORS OFF CLRF PORTA ;CLEAR PORTA CLRF PORTB ;CLEAR PORTB BANKSEL TRISA ;SELECT BANK1 MOVLW b'00000000' ;SET PORTA, ALL OUTPUTS MOVWF TRISA ; MOVLW b'00011111' ;BITS 3,4 ENCODER INPUT, BIT 1 RS232 RX INPUT MOVWF TRISB ; MOVLW b'10000101' ;SET TIMER 0 PARAMETERS ( WE ARE ALREADY IN BANK 1 FOR OPTION REG ) MOVWF OPTION_REG ;DISABLE INT PULL-UPS, ENABLE INTERNAL CLOCK, PRESCALE 256 ; SET BAUD RATE = 9600, No Parity, 1 Stop Bit MOVLW 0x19 ;0x19=9600 bps (0x0C=19200 bps) MOVWF SPBRG MOVLW b'00100100' ;brgh = high (2) MOVWF TXSTA ;ENABLE ASYNC TX, set brgh BANKSEL PORTA ;BACK TO BANK0 MOVLW b'10010000' ;ENABLE ASYNC RX MOVWF RCSTA ;************************************************************ MOVLW b'00000100' ;LOAD START VALUE VAR_1 MOVWF VAR_L MOVLW b'10001000' ;LOAD START VALUE VAR_2 MOVWF VAR_C MOVLW b'00000001' MOVWF LC_VAR ;LOAD LC_VAR START VALUE BSF C_LED CALL SEND_RS232 ;SEND START UP VALUES TO TX LCD AND ATU RECEIVER MOVLW .4 ;ENCODER "PRE-SCALE" VALUE, MOST MECHANICAL ROTARY ENCODERS HAVE FOUR TRANSITIONS, MOVWF DIV_COUNT_DOWN ;BETWEEN EACH INDENT. OPTICAL ENCODERS GENERALY DO NOT HAVE INDENTS.USE 60 FOR OPTICAL ENCODER FOR SMOOTH OPERATION MOVWF DIV_COUNT_UP ; ;***************************************************************************** MOVF ENCODER,W MOVWF OLD ;STRIP OFF ALL BUT THE 2 ENCODER BITS IN OLD. MOVLW B'00011000' ;CREATE BIT MASK FOR 2 ENCODER BITS, BITS 3 AND 4 ANDWF OLD,F ;ONLY ENCODER BITS NOW IN OLD CALL LCD_Init CLRF COUNT_ISR ;CLEAR INTERUPT COUNTER CALL SEND_LCD_CAPACITOR ;ENABLE INTERUPTS BSF INTCON,T0IE ;ENABLE TMR0 INTERUPT BSF INTCON,GIE ;ENABLE GLOBAL INTERUPT ;***************************************************************************** MAIN CALL LC_BUTT_TEST CALL ENCODER_CHECK CALL SEND_LCD GOTO MAIN ;******************************************************************************** LC_BUTT_TEST BTFSS LC_BUTT ;CHECK IF BUTTON PRESSED GOTO RTN ;NO, SO CHECK IF DOWN BUTTON PRESSED CALL DELAY ;WAIT FOR SWITCH BOUNCE BTFSS LC_BUTT ;VALID PRESS SKIP NEXT INSTRUCTION GOTO RTN ;INVALID PRESS, GO TO RETURN BTFSC LC_BUTT ;HAS BUTTON BEEN RELEASED? GOTO $-1 ;NO CALL DELAY ;YES, WAIT FOR SWITCH BOUNCE BTFSC LC_BUTT ;BOUNCE OVER? GOTO $-4 ;NO MOVLW b'00000001' XORWF LC_VAR,F ;TOGGLES LC_VAR BIT 0 EVERY TIME LC BUTTON PRESSED BTFSS LC_VAR,0 GOTO $+3 ; BSF C_LED ;SET L/C LED CALL SEND_LCD_CAPACITOR GOTO RTN ; BCF C_LED ;CLEAR L/C LED CALL SEND_LCD_INDUCTOR RTN RETURN ;********************************************************************************* ENCODER_CHECK MOVF ENCODER,W MOVWF NEW ;MASK OF BITS 3 AND 4 IN NEW. MOVLW b'00011000' ;Create bit mask for 2 BITS (bits 3 & 4). ANDWF NEW,F ;Zero all bits apart from 3 and 4. ;Compare previous encoder inputs (OLD) with latest ones (NEW). MOVF NEW,W ;Move the contents of NEW to TEMP and OLD to W MOVWF TEMP_0 ;in order to compare them with XOR. MOVF OLD,W XORWF TEMP_0,F ;XOR previous inputs (in W) with latest inputs ;(in TEMP) to see if they are equal. BTFSC STATUS,Z ;Test result and skip next line if status zero bit is 0. GOTO Rtrn ;Status zero bit is 1. Previous inputs equal latest ;inputs. Rotary encoder did not move. Return ;to loop. ;STATUS ZERO BIT IS 0. ROTARY ENCODER MOVED. DETERMINE DIRECTION. BCF STATUS,C ;Clear the carry bit in the status register RLF OLD,F ;left shift OLD to align bit 3 of OLD ;with bit 4 of NEW. MOVF NEW,W ;Move the contents of NEW to W in order to XOR. XORWF OLD,F ;XOR previous inputs (in OLD) with latest ;inputs (in W) to determine CW or CCW. BTFSC OLD,4 ;Test bit 4 of result (in OLD). Skip next line ;if it is 0 (direction is CCW). GOTO Up ;Bit is 1 (direction is CW). Go around Down ;and increment counter. Down ;Decrements VAR because encoder moved CCW. DECFSZ DIV_COUNT_DOWN ;HAVE 4/60 TRANSITIONS ELLAPSED,I.E. ONE STEP ON ROTARY? USE 60 TRANSITIONS FOR OPTICAL ENCODER GOTO CONTINUE ;NO BTFSS LC_VAR,0 GOTO TEST_VAR_L MOVLW b'10000000' ;VAR_C ENDSTOP MINIMUM XORWF VAR_C,W BTFSS STATUS,Z GOTO DEC_VAR_C GOTO B4 DEC_VAR_C DECF VAR_C CALL SEND_RS232 B4 MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ;RELOAD COUNTER FOR NEXT TIME GOTO CONTINUE ;BRANCH AROUND UP. TEST_VAR_L MOVLW b'00000000' ;VAR_L ENDSTOP MINIMUM XORWF VAR_L,W BTFSS STATUS,Z GOTO DEC_VAR_L GOTO B5 DEC_VAR_L DECF VAR_L CALL SEND_RS232 B5 MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ;RELOAD COUNTER FOR NEXT TIME GOTO CONTINUE ;BRANCH AROUND UP. Up ;Increments VAR because encoder moved CW. DECFSZ DIV_COUNT_DOWN ;HAVE 4/60 TRANSITIONS ELLAPSED,I.E. ONE STEP ON ROTARY? GOTO CONTINUE ;NO BTFSS LC_VAR,0 GOTO TEST_VAR_L2 MOVLW b'11111111' ;VAR_C ENDSTOP MAX XORWF VAR_C,W BTFSS STATUS,Z GOTO INC_VAR_C GOTO B6 INC_VAR_C INCF VAR_C CALL SEND_RS232 B6 MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ;RELOAD COUNTER FOR NEXT TIME GOTO CONTINUE ;BRANCH AROUND UP. TEST_VAR_L2 MOVLW b'00011011' ;VAR_L ENDSTOP MAX XORWF VAR_L,W BTFSS STATUS,Z GOTO INC_VAR_L GOTO B7 INC_VAR_L INCF VAR_L CALL SEND_RS232 B7 MOVLW .4 ;ENCODER "PRE-SCALE" VALUE MOVWF DIV_COUNT_DOWN ;RELOAD COUNTER FOR NEXT TIME CONTINUE MOVF NEW,W ;SAVE NEW ENCODER READING TO OLD MOVWF OLD Rtrn RETURN ;**************************************************************************************** SEND_RS232 MOVFW VAR_L MOVWF TXREG ;SEND L DATA IN W BANKSEL TRISA ;RAM PAGE 1 BTFSS TXSTA,TRMT ;HAS TX FINISHED? GOTO $-1 ;NO, GO BACK AND WAIT FOR TXSTA,TRMT BIT TO SET HIGH BANKSEL PORTA ;TX FINISHED SO BACK TO RAM PAGE 0 NOP MOVFW VAR_C ;AS ABOVE BUT FOR C DATA MOVWF TXREG BANKSEL TRISA BTFSS TXSTA,TRMT GOTO $-1 BANKSEL PORTA ;BACK TO RAM PAGE 0 RETURN ;************************************************************************************* SEND_LCD CALL LCD_Line1 ;MOVE TO FIRST ROW, FIRST COLUMB MOVLW 'C' ;LOAD A LETTER C CALL LCD_Char ;SEND AS A CHARACTER MOVLW ' ' ;LOAS A SPACE CALL LCD_Char ;SEND AS A CHARACTER CALL CONVERT ;CALL 8 BIT BINARY TO BCD CONVERSION MOVF HUND_C,W ;LOAD 100'S CALL LCD_CharD ;SEND AS A NUMBER MOVF TENS_C,W ;LOAD 10'S CALL LCD_CharD ;SEND A S A NUMBER MOVF ONES_C,W ;LOAD 1'S CALL LCD_CharD ;SEND AS A NUMBER CALL LCD_Line2 ;AS ABOVE BUT FOR L MOVLW 'L' CALL LCD_Char MOVLW ' ' CALL LCD_Char CALL CONVERT MOVF HUND_L,W CALL LCD_CharD MOVF TENS_L,W CALL LCD_CharD MOVF ONES_L,W CALL LCD_CharD RETURN ;***************************************************************************************** SEND_LCD_CAPACITOR CALL LCD_Clr CALL SEND_LCD CALL LCD_TOGGLE_C ;MOVE TO SECOND ROW, COLUMB 11 MOVLW 'C' ;LOAD A LETTER C CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'A' ;LOAD A LETTER A CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'P' ;LOAD A LETTER P CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'A' ;LOAS A LETTER A CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'C' ;LOAD A LETTER C CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'I' ;LOAD A LETTER I CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'T' ;LOAD A LETTER T CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'O' ;LOAD A LETTER O CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'R' ;LOAD A LETTER R CALL LCD_Char ;SEND AS A CHARACTER RETURN ;************************************************************************************* SEND_LCD_INDUCTOR CALL LCD_Clr CALL SEND_LCD CALL LCD_TOGGLE_L ;MOVE TO SECOND ROW, COLUMB 11 MOVLW 'I' ;LOAD A LETTER I CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'N' ;LOAD A LETTER N CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'D' ;LOAD A LETTER D CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'U' ;LOAS A LETTER U CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'C' ;LOAD A LETTER C CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'T' ;LOAD A LETTER T CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'O' ;LOAD A LETTER O CALL LCD_Char ;SEND AS A CHARACTER MOVLW 'R' ;LOAD A LETTER R CALL LCD_Char ;SEND AS A CHARACTER MOVLW ' ' ;LOAD A SPACE CALL LCD_Char ;SEND AS A CHARACTER RETURN ;************************************************************************************* ;THIS ROUTINE COPIED FROM PIC_LIST CONVERT ;VAR_C 8 BIT BINARY TO BCD CONVERSION MOVFW VAR_C ANDLW b'01111111' MOVWF BIN MOVLW .5 MOVWF BIN_COUNT CLRF BCD_L CLRF BCD_H ; we can save some execution time by not ; doing the 'test and add +3'code for the ; first two shifts RLF BIN,F RLF BCD_L,F RLF BIN,F RLF BCD_L,F RLF BIN,F RLF BCD_L,F AGN1 MOVFW BCD_L ADDLW 0x33 MOVWF BIN_TEMP MOVFW BCD_L BTFSC BIN_TEMP,3 ADDLW 0x03 BTFSC BIN_TEMP,7 ADDLW 0x30 MOVWF BCD_L ; we only need to do the test and add +3 for ; the low bcd variable since the ; largest binary value is 0xFF which is 255 ; decimal so the high bcd byte variable will ; never be greater than 2. RLF BIN,F RLF BCD_L,F RLF BCD_H,F DECFSZ BIN_COUNT,F GOTO AGN1 MOVFW BCD_H MOVWF HUND_C MOVFW BCD_L MOVWF TENS_C MOVWF ONES_C SWAPF TENS_C MOVLW b'00001111' ANDWF TENS_C,f MOVLW b'00001111' ANDWF ONES_C,f ;************************************************ ;VAR_L 8 BIT BINARY TO BCD CONVERSION MOVFW VAR_L MOVWF BIN MOVLW .5 MOVWF BIN_COUNT CLRF BCD_L CLRF BCD_H CLRF BIN_TEMP ; we can save some execution time by not ; doing the 'test and add +3'code for the ; first two shifts RLF BIN,F RLF BCD_L,F RLF BIN,F RLF BCD_L,F RLF BIN,F RLF BCD_L,F AGN2 MOVFW BCD_L ADDLW 0x33 MOVWF BIN_TEMP MOVFW BCD_L BTFSC BIN_TEMP,3 ADDLW 0x03 BTFSC BIN_TEMP,7 ADDLW 0x30 MOVWF BCD_L ; we only need to do the test and add +3 for ; the low bcd variable since the ; largest binary value is 0xFF which is 255 ; decimal so the high bcd byte variable will ; never be greater than 2. RLF BIN,F RLF BCD_L,F RLF BCD_H,F DECFSZ BIN_COUNT,F GOTO AGN2 MOVFW BCD_H MOVWF HUND_L MOVFW BCD_L MOVWF TENS_L MOVWF ONES_L SWAPF TENS_L MOVLW b'00001111' ANDWF TENS_L,f MOVLW b'00001111' ANDWF ONES_L,f RETURN ;******************************************************* ;LCD routines ;Initialise LCD LCD_Init CALL LCD_Busy MOVLW 0x20 ;Set 4 bit mode CALL LCD_Cmd MOVLW 0x28 ;Set display shift CALL LCD_Cmd MOVLW 0x06 ;Set display character mode CALL LCD_Cmd MOVLW 0x0c ;Set display on/off and cursor command CALL LCD_Cmd ;Set cursor off CALL LCD_Clr ;clear display RETURN ;************************************************************ ; command set routine LCD_Cmd MOVWF templcd SWAPF templcd,w ;send upper nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BCF LCD_RS ;RS line to 0 CALL Pulse_e ;Pulse the E line high MOVF templcd,w ;send lower nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BCF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high CALL LCD_Busy RETURN ;*************************************************************** LCD_CharD ADDLW 0x30 ;add 0x30 to convert to ASCII LCD_Char MOVWF templcd SWAPF templcd,w ;send upper nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BSF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high MOVF templcd,w ;send lower nibble ANDLW 0x0f ;clear upper 4 bits of W MOVWF LCD_PORT BSF LCD_RS ;RS line to 1 CALL Pulse_e ;Pulse the E line high CALL LCD_Busy RETURN ;******************************************************************* LCD_Busy BANKSEL TRISA ;select bank 1 MOVLW b'00001111' ;set PortA for input MOVWF TRISA ;set TRISA BANKSEL PORTA ;select bank 0 BCF LCD_RS ;set LCD for command mode BSF LCD_RW ;setup to read busy flag BSF LCD_E SWAPF LCD_PORT,W ;swap nibbles and put in W BCF LCD_E MOVWF templcd2 ;put W into temp register BSF LCD_E ;dummy read of lower nibble BCF LCD_E BTFSC templcd2,7 ;test LCD busy flag GOTO LCD_Busy ;if busy check again BCF LCD_RW BANKSEL TRISA ;set bank 1 MOVLW b'00000000' ;set PortA for output MOVWF TRISA BANKSEL PORTA ;set bank 0 RETURN ;************************************************************************** LCD_Line1 MOVLW 0x80 ;move to 1st row, first column CALL LCD_Cmd RETURN LCD_Line2 MOVLW 0xc0 ;move to 2nd row, first column CALL LCD_Cmd RETURN LCD_Line1_MHz MOVLW 0x87 ;move to 1st row, column 8 CALL LCD_Cmd RETURN LCD_Line2S MOVLW 0xc5 ;move to 2nd row, column 5 CALL LCD_Cmd RETURN LCD_TOGGLE_L MOVLW 0xc7 ;move to 2nd row, column 8 CALL LCD_Cmd RETURN LCD_TOGGLE_C MOVLW 0x87 ;move to 1st row, column 8 CALL LCD_Cmd RETURN LCD_CurOn MOVLW 0x0d ;Set display on/off and cursor command CALL LCD_Cmd RETURN LCD_CurOff MOVLW 0x0c ;Set display on/off and cursor command CALL LCD_Cmd RETURN LCD_Clr MOVLW 0x01 ;Clear display CALL LCD_Cmd LCD_LINE1_MEM MOVLW 0x8C CALL LCD_Cmd RETURN RETURN ;************************************************************* Pulse_e BSF LCD_E NOP BCF LCD_E RETURN ;************************************************************ DELAY_3 ;70uS DELAY MOVLW .24 MOVWF dly_count3 LOOP5 DECFSZ dly_count3,1 GOTO LOOP5 RETURN ;*********************************************************************************** DELAY ;55mS DELAY FOR SWITCH BOUNCE MOVLW .100 MOVWF DLY_COUNT1 MOVLW .72 MOVWF DLY_COUNT2 LOOP DECFSZ DLY_COUNT1,1 GOTO LOOP DECFSZ DLY_COUNT2,1 GOTO LOOP RETURN ;********************************************************************** DELAY_2 ;5mS DELAY FOR SWITCH BOUNCE MOVLW .100 MOVWF DLY_COUNT3 MOVLW .7 MOVWF DLY_COUNT4 LOOP1 DECFSZ DLY_COUNT3,1 GOTO LOOP1 DECFSZ DLY_COUNT4,1 GOTO LOOP1 RETURN END